type AsyncFunction<T = any> = () => Promise<T>;

/**
 * 并发执行器 - 用于管理异步函数的并发执行
 * 传入异步函数数组，最多同时执行指定数量的任务
 * 当有任务完成时，自动从队列中取出下一个任务执行
 * 全部任务执行完成后返回 Promise
 */
class ConcurrentExecutor {
  private readonly maxConcurrency: number;

  constructor(maxConcurrency: number = 5) {
    this.maxConcurrency = Math.max(1, maxConcurrency);
  }

  /**
   * 执行异步函数数组
   * @param tasks 异步函数数组
   * @returns Promise，当所有任务执行完成时 resolve
   */
  async execute<T = any>(tasks: AsyncFunction<T>[]): Promise<void> {
    if (!tasks || tasks.length === 0) {
      return Promise.resolve();
    }

    return new Promise<void>((resolve) => {
      const queue = [...tasks]; // 复制数组避免修改原数组
      let runningCount = 0;
      let completedCount = 0;
      const totalTasks = tasks.length;

      const executeNext = () => {
        // 如果队列为空且没有运行中的任务，说明全部完成
        if (queue.length === 0 && runningCount === 0) {
          resolve();
          return;
        }

        // 如果队列为空或已达到最大并发数，不执行新任务
        if (queue.length === 0 || runningCount >= this.maxConcurrency) {
          return;
        }

        // 从队列中取出一个任务
        const task = queue.shift();
        if (!task) {
          return;
        }

        runningCount++;

        // 执行任务
        Promise.resolve()
          .then(task)
          .catch((error) => {
            // 任务失败时停止执行并抛出异常
            // resolve();
            // throw error;
          })
          .finally(() => {
            runningCount--;
            completedCount++;

            // 尝试执行下一个任务
            executeNext();
          });
      };

      // 启动初始任务
      for (let i = 0; i < Math.min(this.maxConcurrency, queue.length); i++) {
        executeNext();
      }
    });
  }
}

export default ConcurrentExecutor;
